Wiki

Clone wiki

Rug.Osc / Osc Addresses as Rug.Osc understands them

The OSC specification is a little ambiguous in regard to how exactly address patterns are to be used and matched so specified here is the detail of how Rug.Osc understands this problem.

Rug.Osc splits osc addresses into 2 distinct types: literal addresses and pattern addresses.

Literal Addresses

A literal address is comprised of one or more parts (often called 'containers' or 'methods' in the osc spec).

Literal address parts must conform to the following conditions:

  • Each part must start with a address separator char '/'.
  • Each part must be at least 2 chars in length including the address separator.
  • Each part may not contain any white space or any of the following chars '#*,/?[]{}'.

The full regular expression for validating literal addresses is listed bellow.

#!c#
@"^/[^\s#\*,/\?\[\]\{}]+((/[^\s#\*,/\?\[\]\{}]+)*)$"

Pattern Addresses

A address pattern is a way of matching many addresses to a single pattern. Address patterns are, like literal addresses, comprised of parts with some amendments.

Each part in in a pattern address is comprised of one or more sub-parts. Sub-parts come in several flavors and maybe used in any combination apart from 'Any Address Depth Match' which may only be present at the start of the address.

Literal

  • May not contain any white space or any of the following chars '#*,/?[]{}'.
  • Will only match if exactly the same string is encountered and is case sensitive.
  • The regular expression for validating literal patterns is @"[^\s#*,/\?[]{}]+"

Wildcards

  • '?' matches exactly one literal char.
  • '*' matches zero or more literal chars.
  • The regular expression for validating wildcard patterns is @"[*\?]+"

Char Span

  • Inclusive mode e.g. '[a-b]' where 'a' and 'b' are literal chars. Matches 1 more chars from within the range from 'a' to 'b' inclusive.
  • Exclusive mode e.g. '[!a-b]' where 'a' and 'b' are literal chars. Matches 1 more chars that are not in the range from 'a' to 'b' inclusive.
  • The regular expression for validating char span patterns is @"[(!?)[^\s#*,/\?[]{}-]-[^\s#*,/\?[]{}-]]"

Char List

  • Inclusive e.g. '[abc]' where 'a', 'b' and 'c' are literal chars. Matches 1 more chars from the list of chars, the order of the chars in the list is irrelevant.
  • Exclusive e.g. '[!abc]' where 'a', 'b' and 'c' are literal chars. Matches 1 more chars that are not present in the list of chars.
  • The regular expression for validating char list patterns is @"[(!?)[^\s#*,/\?[]{}]+]"

Literal List

  • A coma separated list of literal strings e.g. '{str1,str2,str3}'
  • Must contain at least 1 literal.
  • Literals must be at least 1 char in length.
  • No white space is permitted.
  • Matches against exactly one of the literal strings that are present in the list.
  • The regular expression for validating literal list patterns is @"{([^\s#*/\?\,[]{}]+)((,[^\s#*/\?\,[]{}]+)*)}"

Any Address Depth Match

  • '//'
  • May only be present at the start of an address pattern.
  • Matches the remainder of the pattern at any depth in the path. See osc spec 1.1 for more detail.

Address Matching

A regular expression is created for each address pattern. This regex is then used to match any literal address. It is not currently possible for address patterns to match against other address patterns apart from an direct match against the patterns original strings.

Where can address patterns be used?

Address patterns can be used as the address of any osc-message, be it incoming or outgoing, or as filters on incoming messages.

Dealing With Incoming Messages With Pattern Addresses

Using the Rug.Osc.OscNamespaceManager class to handle the invocation of methods that are registered to literal osc addresses is a very useful mechanism but what happens if a message arrives with a pattern address? Rug.Osc.OscNamespaceManager will attempt to 'match' the pattern against any of the literal addresses that have been registered with instance.

Note: It is also possible to use the matching capability of Rug.Osc.OscAddress to roll your own manager class.

#!c#

OscNamespaceManager manager = new OscNamespaceManager();

// Will cause OnTest1 to be invoked when ever the address '/test1' is matched
manager.Attach("/test1", new OscMessageEvent(OnTest1));

// All of the following messages will cause the invocation of the method OnTest1
manager.Invoke(new OscMessage("/test1"));

manager.Invoke(new OscMessage("/*"));

manager.Invoke(new OscMessage("/test*"));

manager.Invoke(new OscMessage("/test[0-9]"));

Filtering Incoming Messages

It may be desirable to filter messages that conform to a particular pattern below is s simple example of how this works.

#!c#

OscNamespaceManager manager = new OscNamespaceManager();

// Will cause OnTestN to be invoked when ever the address pattern '/test[0-9]' is matched
manager.Attach("/test[0-9]", new OscMessageEvent(OnTestN));

// All of the following messages will cause the invocation of the method OnTestN
manager.Invoke(new OscMessage("/test0"));   

manager.Invoke(new OscMessage("/test1"));

manager.Invoke(new OscMessage("/test2"));

manager.Invoke(new OscMessage("/test99"));  

manager.Invoke(new OscMessage("/test[0-9]"));

Notes on address pattern caching

As an speed optimization measure by default Rug.Osc caches the addresses that have been encountered before during the execution of the application. This is handled by the Rug.Osc.OscAddressRegexCache class.

This mechanism assumes that the same addresses will be used multiple times and that there will be a finite number of unique addresses parsed over the course of the execution of the program.

If there are to be many unique addresses used of the course of the execution of the program then it maybe desirable to disable caching.

Updated